home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / examples / demo / opengl / gllandscape.cpp.z / gllandscape.cpp
C/C++ Source or Header  |  2002-04-08  |  18KB  |  681 lines

  1. #include "gllandscape.h"
  2.  
  3. #ifdef Q_WS_MAC
  4. #include <gl.h>
  5. #include <glu.h>
  6. #else
  7. #include <GL/gl.h>
  8. #include <GL/glu.h>
  9. #endif
  10.  
  11. #include <math.h>
  12.  
  13. #include "fbm.h"
  14.  
  15. #ifndef PI
  16. #define PI 3.14159
  17. #endif
  18.  
  19. #if defined(Q_CC_MSVC)
  20. #pragma warning(disable:4305) // init: truncation from const double to float
  21. #pragma warning(disable:4244) // init: truncation from const double to float
  22. #endif
  23.  
  24. GLLandscape::GLLandscape( QWidget * parent, const char * name )
  25.     : QGLWidget( parent, name )
  26. {
  27.     mouseButtonDown  = FALSE;
  28.     animationRunning = FALSE;
  29.     oldX = oldY = oldZ = 0.0;
  30.     landscape     = 0;
  31.     vertexNormals = 0;
  32.     normals       = 0;
  33.     wave          = 0;
  34.     wt            = 0;
  35.     createGrid( 50 );
  36.     setWireframe( 0 );
  37. }
  38.  
  39. GLLandscape::~GLLandscape()
  40. {
  41.     destroyGrid();
  42. }
  43.  
  44. void GLLandscape::initializeGL()
  45. {
  46.     glMatrixMode( GL_MODELVIEW );
  47.     glLoadIdentity();
  48.     glTranslatef( 0.0, 0.0, -50.0 );
  49.     glRotatef( -45, 1, 0, 0 );
  50.     glRotatef( -45, 0, 0, 1 );
  51.     glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[CurrentView].model );
  52.     glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[DefaultView].model );
  53.  
  54.     glMatrixMode( GL_PROJECTION );
  55.     glLoadIdentity();
  56.     /* Use GL utility library function to obtain desired view */
  57.     gluPerspective( 60, 1, 1, 250 );
  58.     glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[CurrentView].projection );
  59.     glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[DefaultView].projection );
  60.  
  61.  
  62.     qglClearColor( black );
  63.     glDepthFunc( GL_LESS );
  64.     calculateVertexNormals();
  65. }
  66.  
  67. void GLLandscape::resizeGL( int width, int height )
  68. {
  69.     glViewport( 0, 0, width, height );
  70. }
  71.  
  72. void GLLandscape::paintGL()
  73. {
  74.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  75.     switch ( mode ) {
  76.     case Wireframe:
  77.         drawWireframe();
  78.         break;
  79.     case Filled:
  80.         drawFilled();
  81.         break;
  82.     case SmoothShaded:
  83.     case Landscape:
  84.         drawSmoothShaded();
  85.         break;
  86.     }
  87. }
  88.  
  89. void GLLandscape::drawWireframe()
  90. {
  91.     qglColor( white );
  92.     glBegin( GL_LINES );
  93.     {
  94.     for ( int y = 0; y < (gridSize-1); y++ )
  95.         for ( int x = 0; x < (gridSize-1); x++) {
  96.         glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
  97.         glVertex3f( x+1-gridHalf, y-gridHalf, landscape[x+1][y] );
  98.         glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
  99.         glVertex3f( x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1] );
  100.  
  101.         glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
  102.         glVertex3f( x-gridHalf, y+1-gridHalf, landscape[x][y+1] );
  103.         }
  104.     }
  105.     glEnd();
  106.     glBegin( GL_LINE_STRIP );
  107.     {
  108.     for ( int x = 0; x < gridSize; x++ ) {
  109.         glVertex3f( x-gridHalf, gridHalf-1, landscape[x][gridSize-1] );
  110.     }
  111.     }
  112.     glEnd();
  113.     glBegin( GL_LINE_STRIP );
  114.     {
  115.     for ( int y = 0; y < gridSize; y++ ) {
  116.         glVertex3f( gridHalf-1, y-gridHalf, landscape[gridSize-1][y] );
  117.     }
  118.     }
  119.     glEnd();
  120. }
  121.  
  122. void GLLandscape::drawFilled()
  123. {
  124.     for ( int y = 0; y < gridSize-1; y++ )
  125.     for ( int x = 0; x < gridSize-1; x++ ) {
  126.         qglColor( red );
  127.         glBegin( GL_TRIANGLE_STRIP );
  128.         {
  129.         glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]);
  130.         glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]);
  131.         glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
  132.         }
  133.         glEnd();
  134.         qglColor( white );
  135.         glBegin( GL_TRIANGLE_STRIP );
  136.         {
  137.         glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]);
  138.         glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]);
  139.         glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
  140.         }
  141.         glEnd();
  142.     }
  143. }
  144.  
  145. void GLLandscape::drawSmoothShaded()
  146. {
  147.     if ( mode == SmoothShaded ) {
  148.     GLfloat materialAmbient[]   = { 0.00, 0.00, 1.0, 0.0 };
  149.     GLfloat materialShininess[] = { 128.0 };
  150.     GLfloat materialSpecular[]  = { 1.0, 1.0, 1.0, 0.0 };
  151.  
  152.     glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
  153.     glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
  154.     glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
  155.     } else {
  156.     GLfloat materialAmbient[]   = { 0.20, 0.33, 0.20, 0.0 };
  157.     GLfloat materialShininess[] = { 1.0 };
  158.     GLfloat materialSpecular[]  = { 0.1, 0.1, 0.1, 0.1 };
  159.  
  160.     glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
  161.     glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
  162.     glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
  163.     }
  164.  
  165.     for ( int y = 0; y < gridSize-1; y++ )
  166.     for ( int x = 0; x < gridSize-1; x++ ) {
  167.         glBegin( GL_POLYGON );
  168.         {
  169.         glNormal3dv(vertexNormals[x][y].n);
  170.         glVertex3f(x-gridHalf,y-gridHalf,landscape[x][y]);
  171.  
  172.         glNormal3dv(vertexNormals[x+1][y].n);
  173.         glVertex3f(x+1-gridHalf, y-gridHalf, landscape[x+1][y]);
  174.  
  175.         glNormal3dv(vertexNormals[x+1][y+1].n);
  176.         glVertex3f(x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1]);
  177.         }
  178.         glEnd();
  179.  
  180.         glBegin( GL_POLYGON );
  181.         {
  182.         glNormal3dv(vertexNormals[x][y].n);
  183.         glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]);
  184.  
  185.         glNormal3dv(vertexNormals[x+1][y+1].n);
  186.         glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]);
  187.  
  188.         glNormal3dv(vertexNormals[x][y+1].n);
  189.         glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
  190.         }
  191.         glEnd();
  192.     }
  193.  
  194.     // Draw water
  195.     if ( mode == Landscape ) {
  196.     GLfloat materialAmbient[]   = { 0.00, 0.00, 1.0, 0.0 };
  197.     GLfloat materialShininess[] = { 128.0 };
  198.     GLfloat materialSpecular[]  = { 1.0, 1.0, 1.0, 0.0 };
  199.  
  200.     glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
  201.     glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
  202.     glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
  203.     
  204.     glEnable( GL_BLEND );
  205.     glBegin( GL_POLYGON );
  206.     {
  207.         glNormal3f( 0, 0, 1 );
  208.         glVertex3f( -gridHalf, -gridHalf, .2 );
  209.         glNormal3f( 0, 0, 1 );
  210.         glVertex3f( -gridHalf, gridHalf, .2 );
  211.         glNormal3f( 0, 0, 1 );
  212.         glVertex3f( gridHalf, gridHalf, .2 );
  213.         glNormal3f( 0, 0, 1 );
  214.         glVertex3f( gridHalf, -gridHalf, .2 );
  215.     
  216.     }
  217.     glEnd();
  218.     glDisable( GL_BLEND );
  219.     }
  220. }
  221.  
  222. void GLLandscape::setGridSize( int size )
  223. {
  224.     destroyGrid();      // destroy old grid
  225.     createGrid( size ); // create new grid
  226.     initializeGL();
  227.     updateGL();
  228. }
  229.  
  230. void GLLandscape::createGrid( int size )
  231. {
  232.     if ( (size % 2) != 0 )
  233.     size++;
  234.     gridSize = size;
  235.     gridHalf = gridSize / 2;
  236.     initFractals  = TRUE;
  237.     landscape     = new double*[gridSize];
  238.     normals       = new gridNormals*[gridSize];
  239.     vertexNormals = new avgNormals*[gridSize];
  240.     wt            = new double*[gridSize];
  241.     wave          = new double*[gridSize];
  242.     for ( int i = 0; i < gridSize; i++ ) {
  243.     landscape[i]     = new double[gridSize];
  244.     normals[i]       = new gridNormals[gridSize];
  245.     vertexNormals[i] = new avgNormals[gridSize];
  246.     wt[i]   = new double[gridSize];
  247.     wave[i] = new double[gridSize];
  248.  
  249.     memset( landscape[i], 0, gridSize*sizeof(double) );
  250.     memset( normals[i], 0, gridSize*sizeof(gridNormals) );
  251.     memset( vertexNormals[i], 0, gridSize*sizeof(avgNormals) );
  252.     memset( wt[i], 0, gridSize*sizeof(double) );
  253.     memset( wave[i], 0, gridSize*sizeof(double) );
  254.     }
  255. }
  256.  
  257. void GLLandscape::destroyGrid()
  258. {
  259.     if ( landscape != NULL ) {
  260.     for( int i = 0; i < gridSize; i++ ) {
  261.         delete[] landscape[i];
  262.         delete[] normals[i];
  263.         delete[] vertexNormals[i];
  264.         delete[] wt[i];
  265.         delete[] wave[i];
  266.     }
  267.     delete[] landscape;
  268.     delete[] normals;
  269.     delete[] vertexNormals;
  270.     delete[] wt;
  271.     delete[] wave;
  272.     }
  273.     landscape = 0;
  274. }
  275.  
  276. void GLLandscape::rotate( GLfloat deg, Axis axis )
  277. {
  278.     makeCurrent();
  279.     glMatrixMode( GL_MODELVIEW );
  280.     for ( int i = 0; i < 2; i++ ) {
  281.     glLoadMatrixf((GLfloat *) views[i].model);
  282.     if ( axis == XAxis )
  283.         glRotatef( deg, 1, 0, 0 );
  284.     else if ( axis == YAxis )
  285.         glRotatef( deg, 0, 1, 0 );
  286.     else
  287.         glRotatef( deg, 0, 0, 1 );
  288.     glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[i].model);
  289.     }
  290.     glLoadMatrixf((GLfloat *) views[CurrentView].model);
  291. }
  292.  
  293. void GLLandscape::rotateX( int deg )
  294. {
  295.     static int oldDeg = 0;
  296.  
  297.     rotate( deg-oldDeg, XAxis );
  298.     oldDeg = deg;
  299.     updateGL();
  300. }
  301.  
  302. void GLLandscape::rotateY( int deg )
  303. {
  304.     static int oldDeg = 0;
  305.  
  306.     rotate( deg-oldDeg, YAxis );
  307.     oldDeg = deg;
  308.     updateGL();
  309. }
  310.  
  311. void GLLandscape::rotateZ( int deg )
  312. {
  313.     static int oldDeg = 0;
  314.  
  315.     rotate( deg-oldDeg, ZAxis );
  316.     oldDeg = deg;
  317.     updateGL();
  318. }
  319.  
  320. void GLLandscape::zoom( int z )
  321. {
  322.     float zoom;
  323.     if ( z < 100 ) {
  324.     zoom = 1 + 4.99 - (z*5.0 / 100.0);
  325.     } else {
  326.     z = 200 - z;
  327.     zoom = z / 100.0;
  328.     }
  329.     makeCurrent();
  330.     glMatrixMode( GL_MODELVIEW );
  331.     // Always scale the original model matrix
  332.     glLoadMatrixf((GLfloat *) views[DefaultView].model);
  333.     glScalef( zoom, zoom, zoom );
  334.     glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[CurrentView].model);
  335.     updateGL();
  336. }
  337.  
  338. void GLLandscape::resetGrid()
  339. {
  340.     setGridSize( gridSize );
  341. }
  342.  
  343. void GLLandscape::fractalize()
  344. {
  345.     Vector p;
  346.     double value;
  347.     double roughness = 0.5;
  348.     int frequency    = 50;
  349.  
  350.     p.x = p.y = p.z = 0;
  351.     // Initialise fbm routine
  352.     if ( initFractals ) {
  353.     initFractals = FALSE;
  354.     value = fBm( p, roughness, 2.0, 8.0, 1 );
  355.     }
  356.  
  357.     // Fractalize grid
  358.     for ( int x = 0; x < gridSize; x++ ) {
  359.     for ( int y = 0; y < gridSize; y++ ) {
  360.         p.x = (double) x / (101 - frequency);
  361.         p.y = (double) y / (101 - frequency);
  362.         p.z = (double) landscape[x][y] / (101 - frequency);
  363.         value = fBm(p, roughness, 2.0, 8.0, 0);
  364.         landscape[x][y] += value;
  365.     }
  366.     }
  367.     calculateVertexNormals();
  368.     updateGL();
  369. }
  370.  
  371.  
  372. //
  373. // Calculate the vector cross product of v and w, store result in n.
  374. //
  375. static void crossProduct( double v[3], double w[3], double n[3] )
  376. {
  377.     n[0] = v[1]*w[2]-w[1]*v[2];
  378.     n[1] = w[0]*v[2]-v[0]*w[2];
  379.     n[2] = v[0]*w[1]-w[0]*v[1];
  380. }
  381.  
  382. void GLLandscape::calculateVertexNormals()
  383. {
  384.     double len, v[3], v2[3], w[3], w2[3], n[3], n2[3];
  385.  
  386.     // Calculate the surface normals for all polygons in the
  387.     // height field
  388.     for ( int i = 0; i < (gridSize-1); i++ )
  389.     for ( int k = 0; k < (gridSize-1); k++ ) {
  390.         /* Lower poly normal */
  391.         v[0] = 1; // (i+1)-i
  392.         v[1] = 0; // k-k
  393.         v[2] = landscape[i+1][k]-landscape[i][k];
  394.         w[0] = 1; // (i+1)-i
  395.         w[1] = 1; // (k+1)-k
  396.         w[2] = landscape[i+1][k+1]-landscape[i][k];
  397.         crossProduct( v, w, n );
  398.         len = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
  399.         normals[i][k].l[0] = n[0]/len;
  400.         normals[i][k].l[1] = n[1]/len;
  401.         normals[i][k].l[2] = n[2]/len;
  402.  
  403.         /* Upper poly normal */
  404.         v2[0] = -1.0; // i-(i+1);
  405.         v2[1] = 0.0;  // (k+1)-(k+1);
  406.         v2[2] = landscape[i][k+1]-landscape[i+1][k+1];
  407.         w2[0] = -1.0; // i-(i+1);
  408.         w2[1] = -1.0; // k-(k+1);
  409.         w2[2] = landscape[i][k]-landscape[i+1][k+1];
  410.         crossProduct( v2, w2, n2 );
  411.         len = sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]);
  412.         normals[i][k].u[0] = n2[0]/len;
  413.         normals[i][k].u[1] = n2[1]/len;
  414.         normals[i][k].u[2] = n2[2]/len;
  415.     }
  416.  
  417.     // Calculate proper vertex normals
  418.     averageNormals();
  419. }
  420.  
  421. void GLLandscape::averageNormals()
  422. {
  423.     // Calculate the average surface normal for a vertex based on
  424.     // the normals of the surrounding polygons
  425.     for ( int i = 0; i < gridSize; i++ )
  426.     for ( int k = 0; k < gridSize; k++ ) {
  427.         if ( i > 0 && k > 0 && i < (gridSize-1) && k < (gridSize-1) ) {
  428.         // For vertices that are *not* on the edge of the height field
  429.         for ( int t = 0; t < 3; t++ ) // X, Y and Z components
  430.             vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
  431.                          normals[i][k].l[t] +
  432.                          normals[i][k-1].u[t] +
  433.                          normals[i-1][k-1].u[t] +
  434.                          normals[i-1][k-1].l[t] +
  435.                          normals[i-1][k].l[t] )/6.0;
  436.         } else {
  437.         // Vertices that are on the edge of the height field require
  438.         // special attention..
  439.         if ( i == 0 && k == 0 ) {
  440.             for ( int t = 0; t < 3; t++ )
  441.             vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
  442.                              normals[i][k].l[t] )/2.0;
  443.         } else if ( i == gridSize-1 && k == gridSize-1 ) {
  444.             for ( int t = 0; t < 3; t++ )
  445.             vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
  446.                              normals[i][k].l[t] )/2.0;
  447.         } else if ( i == gridSize-1) {
  448.             for ( int t = 0; t < 3; t++ )
  449.             vertexNormals[i][k].n[t] = vertexNormals[i-1][k].n[t];
  450.         } else if ( k == gridSize-1 ) {
  451.             for ( int t = 0; t < 3; t++ )
  452.             vertexNormals[i][k].n[t] = vertexNormals[i][k-1].n[t];
  453.         } else if ( k > 0 ) {
  454.             for ( int t = 0; t < 3; t++ )
  455.             vertexNormals[i][k].n[t] = (normals[i][k].u[t] +
  456.                             normals[i][k].l[t] +
  457.                                         normals[i][k-1].u[t])/3.0;
  458.         } else if ( i > 0 ) {
  459.             for ( int t = 0; t < 3; t++ )
  460.             vertexNormals[i][k].n[t] = (normals[i][k].u[t] +
  461.                             normals[i][k].l[t] +
  462.                                         normals[i-1][k].l[t])/3.0;
  463.         }
  464.         }
  465.     }
  466. }
  467.  
  468. void GLLandscape::setWireframe( int state )
  469. {
  470.     if ( state != 1 ) {
  471.     // Enable line antialiasing
  472.     makeCurrent();
  473.     glEnable( GL_LINE_SMOOTH );
  474.     glEnable( GL_BLEND );
  475.     glDisable( GL_DEPTH_TEST );
  476.     glDisable( GL_LIGHTING );
  477.     glDisable( GL_NORMALIZE );
  478.  
  479.     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  480.     glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE );
  481.  
  482.     mode = Wireframe;
  483.     updateGL();
  484.     }
  485. }
  486.  
  487. void GLLandscape::setFilled( int state )
  488. {
  489.     if ( state != 1 ) {
  490.     makeCurrent();
  491.     glEnable( GL_DEPTH_TEST );
  492.     glDisable( GL_LINE_SMOOTH );
  493.     glDisable( GL_BLEND );
  494.     glDisable( GL_LIGHTING );
  495.     glDisable( GL_NORMALIZE );
  496.  
  497.     mode = Filled;
  498.     updateGL();
  499.     }
  500. }
  501.  
  502. void GLLandscape::setSmoothShaded( int state )
  503. {
  504.     if ( state != 1 ) {
  505.     makeCurrent();
  506.     glEnable( GL_DEPTH_TEST );
  507.     glEnable( GL_LIGHTING );
  508.     glEnable( GL_LIGHT0 );
  509.     glEnable( GL_NORMALIZE );
  510.     glDisable( GL_LINE_SMOOTH );
  511.     glDisable( GL_BLEND );
  512.  
  513.     glShadeModel( GL_SMOOTH );
  514.     glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
  515.  
  516.     // Setup lighting and material properties
  517.     GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 };
  518.     GLfloat ambient[]  = { 0.50, 0.50, 0.50, 0.0 };
  519.     GLfloat diffuse[]  = { 1.00, 1.00, 1.00, 0.0 };
  520.     GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 };
  521.     GLfloat materialAmbient[]   = { 0.00, 0.00, 1.0, 0.0 };
  522.         // GLfloat materialDiffuse[]   = { 1.00, 1.00, 1.0, 0.0 };
  523.     GLfloat materialShininess[] = { 128.0 };
  524.     GLfloat materialSpecular[]  = { 1.0, 1.0, 1.0, 0.0 };
  525.  
  526.     glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
  527.         // glMaterialfv( GL_FRONT, GL_DIFFUSE, materialDiffuse );
  528.     glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
  529.     glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
  530.  
  531.     glLightfv( GL_LIGHT0, GL_POSITION, position );
  532.     glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
  533.     glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
  534.     glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
  535.  
  536.     mode = SmoothShaded;
  537.     calculateVertexNormals();
  538.     updateGL();
  539.     }
  540. }
  541.  
  542. void GLLandscape::setLandscape( int state )
  543. {
  544.     if ( state != 1 ) {
  545.     makeCurrent();
  546.     glEnable( GL_DEPTH_TEST );
  547.     glEnable( GL_LIGHTING );
  548.     glEnable( GL_LIGHT0 );
  549.     glEnable( GL_NORMALIZE );
  550.     glDisable( GL_LINE_SMOOTH );
  551.     glDisable( GL_BLEND );
  552.  
  553.     glShadeModel( GL_SMOOTH );
  554.     glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
  555.  
  556.     // Setup lighting and material properties
  557.     GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 };
  558.     GLfloat ambient[]  = { 0.50, 0.50, 0.50, 0.0 };
  559.     GLfloat diffuse[]  = { 1.00, 1.00, 1.00, 0.0 };
  560.     GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 };
  561.     
  562.     glLightfv( GL_LIGHT0, GL_POSITION, position );
  563.     glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
  564.     glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
  565.     glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
  566.  
  567.     glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR );
  568.  
  569.     mode = Landscape;
  570.     calculateVertexNormals();
  571.     updateGL();
  572.     }
  573. }
  574.  
  575. void GLLandscape::mousePressEvent( QMouseEvent *e )
  576. {
  577.     oldPos = e->pos();
  578.     mouseButtonDown = TRUE;
  579. }
  580.  
  581. void GLLandscape::mouseReleaseEvent( QMouseEvent *e )
  582. {
  583.     oldPos = e->pos();
  584.     mouseButtonDown = FALSE;
  585. }
  586.  
  587. void GLLandscape::mouseMoveEvent( QMouseEvent *e )
  588. {
  589.     GLfloat rx = (GLfloat) (e->x() - oldPos.x()) / width();
  590.     GLfloat ry = (GLfloat) (e->y() - oldPos.y()) / height();
  591.  
  592.     if ( e->state() == LeftButton ) {
  593.     // Left button down - rotate around X and Y axes
  594.     oldX = 180*ry;
  595.     oldY = 180*rx;
  596.     rotate( oldX, XAxis );
  597.     rotate( oldY, YAxis );
  598.     updateGL();
  599.     } else if ( e->state() == RightButton ) {
  600.     // Right button down - rotate around X and Z axes
  601.     oldX = 180*ry;
  602.     oldZ = 180*rx;
  603.     rotate( oldX, XAxis );
  604.     rotate( oldZ, ZAxis );
  605.     updateGL();
  606.     }
  607.     oldPos = e->pos();
  608. }
  609.  
  610. void GLLandscape::timerEvent( QTimerEvent * )
  611. {
  612.     int dx, dy; // disturbance point
  613.     float s, v, W, t;
  614.     int i, j;
  615.  
  616.     if ( mode == Landscape ) {
  617.     dx = dy = 0;
  618.     } else {
  619.     dx = dy = gridSize >> 1;
  620.     }
  621.     W = 0.3;
  622.     v = -4; // wave speed
  623.  
  624.     for ( i = 0; i < gridSize; i++ )
  625.     for ( j = 0; j < gridSize; j++ )
  626.     {
  627.         s = sqrt( (double) ( (j - dx) * (j - dx) + (i - dy) * (i - dy) ) );
  628.         wt[i][j] += 0.1;
  629.         t = s / v;
  630.  
  631.         if ( mode == Landscape ) {
  632.         if ( (landscape[i][j] + wave[i][j]) < 0 )
  633.             landscape[i][j] -= wave[i][j];
  634.         if ( (dy - j != 0) || (dx - i != 0) )
  635.             wave[i][j] = (3 * sin( 2 * PI * W * (wt[i][j] + t ))) / 
  636.                  (0.2*(sqrt( pow((double)(dx-i), 2) + pow((double)(dy-j), 2))+2));
  637.         else
  638.             wave[i][j] = ( 3 * sin( 2 * PI * W * ( wt[i][j] + t ) ) );
  639.         if ( landscape[i][j] + wave[i][j] < 0 )
  640.             landscape[i][j] += wave[i][j];
  641.  
  642.         } else {
  643.         landscape[i][j] -= wave[i][j];
  644.  
  645.         if ( s != 0 )
  646.             wave[i][j] = 2 * sin(2 * PI * W * ( wt[i][j] + t )) / 
  647.                  (0.2*(s + 2));
  648.         else
  649.             wave[i][j] = 2 * sin( 2 * PI * W * ( wt[i][j] + t ) );
  650.         landscape[i][j] += wave[i][j];
  651.         }
  652.         
  653.     }
  654.     if ( mode == SmoothShaded || mode == Landscape )
  655.     calculateVertexNormals();
  656.     updateGL();
  657. }
  658.  
  659. void GLLandscape::toggleWaveAnimation( bool state )
  660. {
  661.     if ( state ) {
  662.      startTimer( 20 );
  663.     animationRunning = TRUE;
  664.     } else {
  665.     killTimers();
  666.     animationRunning = FALSE;
  667.     }
  668. }
  669.  
  670. void GLLandscape::showEvent( QShowEvent * )
  671. {
  672.     if ( animationRunning )
  673.      startTimer( 20 );    
  674. }
  675.  
  676. void GLLandscape::hideEvent( QHideEvent * )
  677. {
  678.     if ( animationRunning )
  679.     killTimers();
  680. }
  681.